﻿//=============================================================================
// Project  : NIPO Component Framework
// File    : NIPOInstance.cs
// Author  : Bernhard Dieber (Bernhard.Dieber@uni-klu.ac.at)
// Copyright 2010 by Bernhard Dieber
// This code is published under the Microsoft Public License (Ms-PL).  A copy
// of the license should be distributed with the code.  It can also be found
// at the project website: http://NIPO.CodePlex.com.   This notice, the
// author's name, and all copyright notices must remain intact in all
// applications, documentation, and source files.
//=============================================================================

using System;
using System.Collections.Generic;
using NIPO.Plugins;

namespace NIPO.Controller
{
    /// <summary>
    /// Represents a NIPO instance consisting of Input, Processing, Output, Service and Observer plugins
    /// </summary>
    internal sealed class NIPOInstance
    {
        private readonly List<InputPlugin> _inputPlugins = new List<InputPlugin>();
        private readonly List<OutputPlugin> _outputPlugins = new List<OutputPlugin>();
        private readonly List<ServicePlugin> _servicePlugins = new List<ServicePlugin>();
        private ProcessingPlugin _processingPlugin = null;
        private readonly List<ObserverPlugin> _observerPlugins = new List<ObserverPlugin>();

        /// <summary>
        /// Returns all selected plugins of all categories
        /// </summary>
        internal ICollection<Plugin> Plugins
        {
            get
            {
                List<Plugin> plugins =
                    new List<Plugin>(_inputPlugins.Count + _outputPlugins.Count + _servicePlugins.Count +
                                                 _observerPlugins.Count + 1);
                plugins.AddRange(_inputPlugins.ConvertAll(source => (Plugin) source));
                if (ProcessingPlugin != null)
                    plugins.Add(_processingPlugin);
                plugins.AddRange(_outputPlugins.ConvertAll(source => (Plugin) source));
                plugins.AddRange(_observerPlugins.ConvertAll(source => (Plugin) source));
                plugins.AddRange(_servicePlugins.ConvertAll(source => (Plugin) source));
                return plugins;
            }
        }
        
        

        /// <summary>
        /// Gets the input plugins.
        /// </summary>
        /// <value>The input plugins.</value>
        internal ICollection<InputPlugin> InputPlugins
        {
            get
            {
                return _inputPlugins;
            }

        }

        /// <summary>
        /// Gets the output plugins.
        /// </summary>
        /// <value>The output plugins.</value>
        internal ICollection<OutputPlugin> OutputPlugins
        {
            get
            {
                return _outputPlugins;
            }

        }

        /// <summary>
        /// Gets the services.
        /// </summary>
        /// <value>The services.</value>
        internal ICollection<ServicePlugin> Services
        {
            get
            {
                return _servicePlugins;
            }
        }

        /// <summary>
        /// Gets the observers.
        /// </summary>
        /// <value>The observers.</value>
        internal ICollection<ObserverPlugin> Observers
        {
            get
            {
                return _observerPlugins;
            }

        }

        /// <summary>
        /// Gets or sets the processing plugin.
        /// </summary>
        /// <value>The processing plugin.</value>
        internal ProcessingPlugin ProcessingPlugin
        {
            get { return _processingPlugin; }
            set { _processingPlugin = value; }
        }

        /// <summary>
        /// Adds an input plugin.
        /// </summary>
        /// <param name="inputPlugin">The input plugin.</param>
        internal void AddInputPlugin(InputPlugin inputPlugin)
        {
            if (!_inputPlugins.Contains(inputPlugin))
            {
                _inputPlugins.Add(inputPlugin);
            }
        }

        /// <summary>
        /// Clears this instance. Disposes all plugins and clears the list of IPO, Service and Observer plugins
        /// </summary>
        internal void Clear()
        {
            _inputPlugins.Clear();
            _outputPlugins.Clear();
            _processingPlugin = null;
            _servicePlugins.Clear();
            _observerPlugins.Clear();
        }
        /// <summary>
        /// Adds an output plugin.
        /// </summary>
        /// <param name="outputPlugin">The output plugin.</param>
        internal void AddOutputPlugin(OutputPlugin outputPlugin)
        {
            if (!_outputPlugins.Contains(outputPlugin))
            {
                _outputPlugins.Add(outputPlugin);
            }
        }

        /// <summary>
        /// Adds a service plugin.
        /// </summary>
        /// <param name="servicePlugin">The service plugin.</param>
        internal void AddServicePlugin(ServicePlugin servicePlugin)
        {
            if (!_servicePlugins.Contains(servicePlugin))
            {
                _servicePlugins.Add(servicePlugin);
                Service.AddService(servicePlugin);
            }
        }

        /// <summary>
        /// Adds an observer plugin.
        /// </summary>
        /// <param name="observer">The observer.</param>
        internal void AddObserverPlugin(ObserverPlugin observer)
        {
            if (!_observerPlugins.Contains(observer))
            {
                _observerPlugins.Add(observer);
            }
        }
    }
}